﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.VisualStudio.TextTemplating;
using System.CodeDom.Compiler;

namespace org.iringtools.utility
{
  public class CustomTextTemplateHost : ITextTemplatingEngineHost
  {
    public string TemplateFileValue = String.Empty;
    public string TemplateFile
    {
      get { return TemplateFileValue; }
    }

    private string fileExtensionValue = ".cs";
    public string FileExtension
    {
      get { return fileExtensionValue; }
    }

    private Encoding fileEncodingValue = Encoding.UTF8;
    public Encoding FileEncoding
    {
      get { return fileEncodingValue; }
    }

    private CompilerErrorCollection errorsValue;
    public CompilerErrorCollection Errors
    {
      get { return errorsValue; }
    }

    public IList<string> StandardAssemblyReferences
    {
      get
      {
        return new string[]
        {
            typeof(System.Uri).Assembly.Location
        };
      }
    }

    public IList<string> StandardImports
    {
      get
      {
        return new string[]
        {
            "System"
        };
      }
    }

    public bool LoadIncludeText(string requestFileName, out string content, out string location)
    {
      content = System.String.Empty;
      location = System.String.Empty;

      if (File.Exists(requestFileName))
      {
        content = File.ReadAllText(requestFileName);
        return true;
      }
      else
      {
        return false;
      }
    }

    public object GetHostOption(string optionName)
    {
      object returnObject;
      switch (optionName)
      {
        case "CacheAssemblies":
          returnObject = true;
          break;
        default:
          returnObject = null;
          break;
      }
      return returnObject;
    }

    public string ResolveAssemblyReference(string assemblyReference)
    {
      if (File.Exists(assemblyReference))
      {
        return assemblyReference;
      }

      string candidate = assemblyReference;
      if (File.Exists(candidate))
      {
        return candidate;
      }

      return "";
    }

    public Type ResolveDirectiveProcessor(string processorName)
    {
      if (string.Compare(processorName, "XYZ", StringComparison.OrdinalIgnoreCase) == 0)
      {
        //return typeof();
      }
      throw new Exception("Directive Processor not found");
    }

    public string ResolvePath(string fileName)
    {
      if (fileName == null)
      {
        throw new ArgumentNullException("the file name cannot be null");
      }

      if (File.Exists(fileName))
      {
        return fileName;
      }

      string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), fileName);
      if (File.Exists(candidate))
      {
        return candidate;
      }

      return fileName;
    }

    public string ResolveParameterValue(string directiveId, string processorName, string parameterName)
    {
      if (directiveId == null)
      {
        throw new ArgumentNullException("the directiveId cannot be null");
      }
      if (processorName == null)
      {
        throw new ArgumentNullException("the processorName cannot be null");
      }
      if (parameterName == null)
      {
        throw new ArgumentNullException("the parameterName cannot be null");
      }

      return String.Empty;
    }

    public void SetFileExtension(string extension)
    {
      fileExtensionValue = extension;
    }

    public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective)
    {
      fileEncodingValue = encoding;
    }

    public void LogErrors(CompilerErrorCollection errors)
    {
      errorsValue = errors;
    }

    public AppDomain ProvideTemplatingAppDomain(string content)
    {
      return AppDomain.CreateDomain("Generation App Domain");
    }
  }
}
